﻿#include "asycipc/heartbeat.hpp"

#include <algorithm>
#include <stdexcept>

namespace asycipc {

HeartbeatMonitor::HeartbeatMonitor(
    std::chrono::milliseconds interval,
    uint32_t allowed_miss,
    std::chrono::steady_clock::time_point now)
    : interval_(interval),
      allowed_miss_(allowed_miss),
      last_send_(now),
      last_receive_(now) {
  if (interval_.count() <= 0) {
    throw std::invalid_argument("heartbeat interval must be positive");
  }
}

bool HeartbeatMonitor::ShouldSend(
    std::chrono::steady_clock::time_point now) const {
  return now - last_send_ >= interval_;
}

void HeartbeatMonitor::MarkSent(std::chrono::steady_clock::time_point now) {
  last_send_ = now;
}

void HeartbeatMonitor::MarkReceived(
    std::chrono::steady_clock::time_point now) {
  last_receive_ = now;
}

bool HeartbeatMonitor::IsExpired(
    std::chrono::steady_clock::time_point now) const {
  const auto timeout = interval_ * (allowed_miss_ + 1);
  return now - last_receive_ > timeout;
}

}  // namespace asycipc
